﻿//CustomClass Template - Created by CodenameGamma
//Replace Layout with the CC name, 
//and WoWClass.Mage with the Class your Designing for.
//Created July, 3rd 2010
//For use with Honorbuddy
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.IO;
using System.Drawing;
using Styx;
using Styx.Combat.CombatRoutine;
using Styx.Helpers;
using Styx.Logic;
using Styx.Logic.Combat;
using Styx.Logic.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;

namespace LimbSplitter
{
    class Classname : CombatRoutine
    {
        public override sealed string Name { get { return "Limb Splitter v1.0"; } }

        public override WoWClass Class { get { return WoWClass.Warrior; } }

		private static LocalPlayer Me { get { return ObjectManager.Me; } }
               
        #region Log
        private void slog(string format, params object[] args) //use for slogging
        {
            Logging.Write(format, args);
        }
        #endregion
        

        #region Initialize
        public override void Initialize()
        {
			Logging.Write(Color.White, "___________________________________________________");
            Logging.Write(Color.Crimson, "-------- Limb Splitter v1.0 CC by Shaddar --------");
			Logging.Write(Color.Crimson, "-----  Remember to comment on the forum! --");
			Logging.Write(Color.Crimson, "-------- /like and +rep if you like this CC! ------");
			Logging.Write(Color.White, "___________________________________________________");
			Logging.Write(Color.White, "_I would like to thank these for helping me out!_");
			Logging.Write(Color.Crimson, "__________xLegendx, Stree and Daorigin__________");
			Logging.Write(Color.Crimson, "___CodenameG, Nomnomnom, Mahe4, Jasf10__");
			Logging.Write(Color.White, "__________________and Macphee!____________________");
        }  
        #endregion

        #region Settings

        public override bool WantButton
        {
            get
            {
                return true;
            }
        }

        public override void OnButtonPress()
        {
            Logging.Write(Color.Aqua, "No configuration yet!");
        }
        #endregion

		#region Add Detection
        //Credit to CodeNameGamma for detectAdds code
        private List<WoWUnit> adds = new List<WoWUnit>();

		private List<WoWUnit> detectAdds()
        {
            if (Me.CurrentTarget != null)
            {
                List<WoWUnit> addList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                            unit.Guid != Me.Guid &&
                            unit.Location.Distance(Me.CurrentTarget.Location) <= 10 &&
							(unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
                            !unit.IsFriendly &&
                            !unit.IsPet &&
                            !Styx.Logic.Blacklist.Contains(unit.Guid));

                if (addList.Count > 1)
                {
                    Logging.Write(Color.Crimson, "Detected " + addList.Count.ToString() + " adds! Switchting to AoE mode!");
                }
                return addList;
            }
            else
            {
                return null;
            }
            
        }  
		private bool IsTargetBoss()
        {
            string UnitClassification = Lua.GetReturnValues("local classification = UnitClassification(\"target\"); return classification")[0];
            string UnitLevel = Lua.GetReturnValues("local level = UnitLevel(\"target\"); return level")[0];
            if (!Me.IsInRaid)
            {
                if (UnitClassification == "worldboss" ||
                   (Me.CurrentTarget.Level == 87 && Me.CurrentTarget.Elite && Me.CurrentTarget.MaxHealth >= 3500000) ||
                   (Me.CurrentTarget.Level == 898))
                    return true;

                else return false;
            }
            else
            {
                if (UnitLevel == "-1")
                    return true;

                else return false;
            }
            
            
        }
        #endregion

        #region CastSpell Method
        // Credit to Apoc for the below CastSpell code
        // Used for calling CastSpell in the Combat Rotation
        public bool CastSpell(string spellName)
        {
            if (SpellManager.CanCast(spellName))
            {
                SpellManager.Cast(spellName);
                // We managed to cast the spell, so return true, saying we were able to cast it.
                return true;
            }
            // Can't cast the spell right now, so return false.
            return false;
        }
		public bool CastBuff(string name)
        {
            if (!PlayerHasBuff(name) && SpellManager.CanBuff(name, Me))
            {
                SpellManager.Cast(name);
                slog(name);
                return true;
            }
            return false;
        }

        public bool PlayerHasBuff(string name)
        {
            return PlayerBuffTimeLeft(name) > 0;
        }

        public bool TargetHasDebuff(string name)
        {
            return TargetDebuffTimeLeft(name) != 0; // <0 means passive aura; >0 means active one
        }
		public double PlayerBuffTimeLeft(string name)
        {
            try
            {
                var lua = string.Format("local x=select(7, UnitBuff('player', \"{0}\", nil, 'PLAYER')); if x==nil then return 0 else return x-GetTime() end", Lua.Escape(name));
                var t = double.Parse(Lua.GetReturnValues(lua)[0]);
                return t;
            }
            catch
            {
                slog("Lua failed in AuraTimeLeft");
                return 999999;
            }
        }

        private double TargetDebuffTimeLeft(string DebuffName)
        {
            return double.Parse(Lua.GetReturnValues(string.Format("local expirationTime = select(7, UnitDebuff(\"target\", \"{0}\", nil, \"player\")); " +
                                     "if expirationTime == nil then return 0 else return expirationTime - GetTime() end", DebuffName))[0]);
        }

        public double TargetDebuffTimeLeftAll(string name)
        {
            try
            {
                var lua = string.Format("local x=select(7, UnitDebuff(\"target\", \"{0}\", nil)); if x==nil then return 0 else return x-GetTime() end", Lua.Escape(name));
                var t = double.Parse(Lua.GetReturnValues(lua)[0]);
                return t;
            }
            catch
            {
                slog("Lua failed in TargetAuraTimeLeft");
                return 999999;
            }
        }
		

		private bool NeedStackExecutioner()
		{
			return !Me.HasAura("Executioner") || Me.Auras["Executioner"].StackCount < 5 || Me.Auras["Executioner"].TimeLeft.Seconds <= 3;
		}
        #endregion

        #region CombatStart


        private void AutoAttack()
        {
            if (!Me.IsAutoAttacking && Me.CurrentTarget.Distance <=7d)
            {
                Lua.DoString("StartAttack()");
            }
        }
        #endregion

        #region Combat
      
        public override void Combat()
        {
            adds = detectAdds();

            if (Me.CurrentTarget != null  && Me.CurrentTarget.IsAlive == true && Me.Mounted == false)
            {
				
///////////////////////////////////////////////Shouts////////////////////////////////////////////////////////////////////////////////////////////////

				{
				if (Me.Combat && Me.RagePercent < 30)
					{
					if (CastSpell("Battle Shout"))
						{
						Logging.Write(Color.Red, ">> Battle Shout <<");
						}
					}
				}

/////////////////////////////////////////////Cooldowns are here////////////////////////////////////////////////////////////////////////////////////////////////
			
			}
            if (Me.CurrentTarget.Distance <=10d && Me.CurrentTarget != null  && Me.CurrentTarget.IsAlive == true && Me.Mounted == false)
            {

				{
				if (!PlayerHasBuff("Enrage") && IsTargetBoss())
					{
					if (CastSpell("Death Wish"))
						{
						Logging.Write(Color.Red, ">> Death Wish <<");
						}
					}
				}
				{
				if ((PlayerHasBuff("Death Wish") || SpellManager.Spells["Death Wish"].CooldownTimeLeft.TotalSeconds > 100) && IsTargetBoss())
					{
					if (CastSpell("Recklessness"))
						{
						Logging.Write(Color.FloralWhite, ">> Recklessness <<");
						}
					}
				}
				{
				if (Me.RagePercent < 20 || !PlayerHasBuff("Death Wish") || !PlayerHasBuff("Enrage"))
					{
					if (CastSpell("Berserker Rage"))
						{
                        Logging.Write(Color.FloralWhite, ">> Berserker Rage <<");
						}
					}
				}
				{
				if (Me.RagePercent > 55)
					{
                    if (CastSpell("Inner Rage"))
						{
                        Logging.Write(Color.Crimson, ">> Inner Rage <<");
						}
					}
				}
				{
				if (IsTargetBoss())
					{
					Lua.DoString("RunMacroText('/use 13');");
					}
				}
				{
				if (IsTargetBoss())
					{
					Lua.DoString("RunMacroText('/use 14');");
					}
				}
				{
				if (IsTargetBoss())
					{
					Lua.DoString("RunMacroText('/use 10');");
					}
				}

//////////////////////////////////////////////////Racial Skills here/////////////////////////////////////////////////////////////////////////////////////////
				
				{
				if (IsTargetBoss())
					Lua.DoString("RunMacroText('/Cast Berserking');");
				}
				{
				if (IsTargetBoss())
					Lua.DoString("RunMacroText('/Cast Blood Fury');");
				}

/////////////////////////////////////////////AoE Rotation here/////////////////////////////////////////////////////////////////////////////////////////////////

			}
            if (Me.CurrentTarget.Distance <=10d && Me.CurrentTarget != null  && Me.CurrentTarget.IsAlive == true && Me.Mounted == false)
            {

				{
				if (adds.Count >=3)
					{
					if(CastSpell("Inner Rage"))
						{
						Logging.Write(Color.Aqua, ">> Inner Rage <<");
						}
					}
				}
				{
				if (adds.Count >=4)
					{
					if (CastSpell("Whirlwind"))
						{
						Logging.Write(Color.Aqua, ">> Whirlwind <<");
						}
					}
				}
				{
				if (adds.Count >=3)
					{
					if (CastSpell("Cleave"))
						{
						Logging.Write(Color.Aqua, ">> Cleave <<");
						}
					}
				}
				{
				if (adds.Count ==3)
					{
					if (CastSpell("Bloodthirst"))
						{
						Logging.Write(Color.Aqua, ">> Whirlwind <<");
						}
					}
				}
				
/////////////////////////////////////////////Single Target DPS here////////////////////////////////////////////////////////////////////////////////////////////
			
			}
            if (adds.Count <=2 && Me.CurrentTarget != null  && Me.CurrentTarget.IsAlive == true && Me.Mounted == false)
            {

				{
				if (Me.RagePercent >= 60 && Me.CurrentTarget.HealthPercent >=20)
					{
					if (CastSpell("Heroic Strike"))           
						{
                        Logging.Write(Color.Aqua, ">> Heroic Strike <<");
						}
                    }
                }
				{
                if (!TargetHasDebuff("Colossus Smash"))
					{
					if (CastSpell("Colossus Smash"))           
						{
                        Logging.Write(Color.Aqua, ">> Colossus Smash <<");
						}
                    }
                }
				{
				if (Me.CurrentTarget.HealthPercent <=20 && NeedStackExecutioner())
					{
					if (CastSpell ("Execute"))
						{
						Logging.Write(Color.Red, ">> Execute! <<");
						}
					}
				}
				{
				if (PlayerHasBuff("Enrage") || PlayerHasBuff("Berserker Rage") || PlayerHasBuff("Death Wish"))
					{
					if (CastSpell("Raging Blow"))
						{
						Logging.Write(Color.Red, ">> Raging Blow <<");
						}
					}
				}
				{
				if (CastSpell("Bloodthirst"))
					{
					Logging.Write(Color.Red, ">> Bloodthirst <<");
					}
				}
				{
				if (PlayerHasBuff("Bloodsurge"))
					{
					if (CastSpell("Slam"))
						{
						Logging.Write(Color.Red, ">> Slam <<");
						}
					}
				}							             
			
            }       

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				
               
            
        }  
  
        #endregion

    }
}